package com.zsj.juc.lock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author zsj
 * @version 1.0
 * @date 2024/5/17 12:38
 * @description 自旋锁
 * <p>
 * <p>
 * CAS实现
 */
@Slf4j
public class SpinLockDemo {


    private final AtomicReference<Thread> reference = new AtomicReference<>();

    public void lock() {
        Thread thread = Thread.currentThread();//获取到当前的线程
        log.info("{} come in", thread.getName());
        while (!reference.compareAndSet(null, thread)) {//无限循环直到获取到
            //必须要源自类中没有其它线程在使用才能去抢夺
            log.info("{} 终于得吃了", thread.getName());
        }
        log.info("{} get lock", thread.getName());
    }

    public void unlock() {
        Thread thread = Thread.currentThread();//当前线程
        reference.compareAndSet(thread, null);//释放资源
        log.info("{} release lock", thread.getName());
    }


    public static void main(String[] args) {
        SpinLockDemo spinLockDemo = new SpinLockDemo();
        new Thread(() -> {
            spinLockDemo.lock();
            try {
                TimeUnit.MILLISECONDS.sleep(5000);
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
            spinLockDemo.unlock();
        }, "a").start();

        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }

        new Thread(() -> {
            spinLockDemo.lock();
            try {
                TimeUnit.MILLISECONDS.sleep(1000);
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
            spinLockDemo.unlock();
        }, "b").start();

    }
}
